Skip to content

Bug fixes and improvements#946

Open
HarleyGilpin wants to merge 7 commits intoGregHib:mainfrom
HarleyGilpin:main
Open

Bug fixes and improvements#946
HarleyGilpin wants to merge 7 commits intoGregHib:mainfrom
HarleyGilpin:main

Conversation

@HarleyGilpin
Copy link
Copy Markdown
Contributor

@HarleyGilpin HarleyGilpin commented Apr 10, 2026

Bug Fix: NPCs spawned under a target couldn't attack

Summary

NPCs spawned under a target couldn't attack because Interact mode (used for the initial attack interaction) had no logic to step out from under the target, unlike CombatMovement which explicitly handles this case.

Root Cause

When an NPC with allowed_under = false is on the same tile as its target, the following chain of failures occurs:

Step What Happens
Movement.arrived() Returns false (overlap check fails)
calculate() Queues a no-op step (naive destination = current tile when overlapping)
super.tick() Consumes the no-op step with no movement
cantReach() Called, interaction is cleared, NPC gives up

Fix

Interact.kt (tick()): Before the normal calculate() / processInteraction() flow, check if the NPC is under its target and not allowed there. If so, mirror CombatMovement.stepOut() behavior:

  1. Clear any stale steps
  2. Pick a random cardinal direction
  3. Queue a step in that direction if passable
  4. Call super.tick() to execute the step

This lets the NPC move out from under the target on the first tick, allowing combat to initialize normally on the second tick.

Test

CombatMovementTest.kt: Creates a guard NPC spawned at the same tile as a player, calls interactPlayer(player, "Attack"), ticks twice, and verifies the NPC has moved away and transitioned to CombatMovement.

Demo

Screencast_20260410_061246.webm

Bug Fix: Character creation screen skipped for new accounts

Summary

New accounts were not shown the character_creation interface on first login.

Root Cause

AccountManager.create() was setting the "creation" timestamp immediately when a new player record was created. Introduction.welcome() uses the presence of "creation" to detect returning players and skip the screen, so new accounts were being mistaken for returning players before they ever logged in.

Fix

Removed "creation" from AccountManager.create(). The timestamp is already set by Introduction.setup() after the character_creation interface closes, which is the correct point in time. Updated the corresponding test to no longer assert the premature value.


Bug Fix: Dragon claws special attack damage and hit timing

Summary

Fixes the dragon claws "Slice and Dice" special attack (DragonClaws.kt) to match the 2011 behavior. There were three damage formula bugs and a fundamental engine-level timing issue causing all four hits to land on the same tick.

Damage Formula Fixes

Scenario Bug Fix
4-2-1-1 Hit 1 upper bound was maxHit - 10 Changed to maxHit - 1 (i.e. nextInt(maxHit/2, maxHit))
All scenarios Hit 4 was hit3 + random(0, 10) Changed to hit3 + 1, confirmed by documented examples (35-17-8-9, 0-30-15-16, 0-0-22-23)
All-miss Fallback was random 0 or 10 per hit Changed to ~2/3 chance of 2 total damage split randomly between hits 3 and 4, ~1/3 true 0-0-0-0

Hit Timing Fix

All four hitsplats were landing on the same tick. The spec requires two pairs: hits 1 & 2 on the activation tick, hits 3 & 4 on the following tick (0.6 seconds later).

Root cause: ActionQueue.tick() runs a while (queue.isNotEmpty()) loop that calls removeIf repeatedly, decrementing remaining on every pass. This fast-forwards any delayed actions within the same tick, so initialDelay = 2 would get decremented to 0 over two passes in a single queue.tick() call, regardless of the delay value passed to hit().

Fix: Instead of passing a delay to the final two hit() calls, hits 3 and 4 are now dispatched from inside a strongQueue proxy action on the target. Because strongQueue adds to pending (not queue), and queuePending() only runs at the start of the next queue.tick(), anything added to pending during an active queue.tick() is naturally deferred by one full tick, with no delay arithmetic needed.

Copy link
Copy Markdown
Owner

@GregHib GregHib left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! Admittedly this does need a proper architecture solution but this will be a nice short term fix

@HarleyGilpin
Copy link
Copy Markdown
Contributor Author

Thanks for the contribution! Admittedly this does need a proper architecture solution but this will be a nice short term fix

Thanks for your feed back, I moved step-out logic from CombatMovement into Movement. Since "step out from under a character target" is a movement concern rather than a combat concern, the logic was moved to Movement (the base class) where it applies to all modes automatically. The shape == -2 guard scopes it to character targets only, and the shouldQueueStepOut() hook lets CombatMovement skip queuing a random step when both characters are already in active combat movement, clearing the stale steps and letting normal recalculation take over instead.

@HarleyGilpin HarleyGilpin changed the title Fix: NPCs spawned under a target couldn't attack fix(2026-04-11): multiple bug fixes to resolve reported user issues Apr 11, 2026
@HarleyGilpin HarleyGilpin changed the title fix(2026-04-11): multiple bug fixes to resolve reported user issues fix: multiple bug fixes to resolve reported user issues Apr 11, 2026
@HarleyGilpin HarleyGilpin changed the title fix: multiple bug fixes to resolve reported user issues fix: bugs related to npc movement and player account creation. Apr 11, 2026
@HarleyGilpin HarleyGilpin changed the title fix: bugs related to npc movement and player account creation. fix: a variety of bugs addressed Apr 12, 2026
@HarleyGilpin HarleyGilpin changed the title fix: a variety of bugs addressed fix: smashed a variety of user bug reports Apr 12, 2026
@HarleyGilpin HarleyGilpin changed the title fix: smashed a variety of user bug reports Bug fixes and improvements Apr 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants